//
//  AccountingBudget.swift
//  KoiAccounting
//
//  Created by 纪洪文 on 16.03.25.
//

import Foundation
import GRDB

struct AccountingBudget : Codable, Identifiable, FetchableRecord, MutablePersistableRecord {
    var id:Int?
    var amount: Double?
    var budgetId: String?
    var cid: String?
    var bookId: String?
    var uid: String?
    var createTime: String?
    var updateTime: String?
    var isTotal: Int? = 0
    var isDel: Int? = 0
    var sv: Int64? = 0
    
    // 定义数据库表
    static let databaseTableName = "accounting_budget"
    
    enum CodingKeys: String, CodingKey {
        case id, amount, budgetId = "budget_id", cid, bookId = "book_id", uid, isTotal = "is_total", createTime = "create_time", updateTime = "update_time",  isDel = "is_del", sv
    }
    
    enum Columns: String, ColumnExpression {
        case id, amount, budgetId = "budget_id", cid, bookId = "book_id", uid, isTotal = "is_total", createTime = "create_time", updateTime = "update_time", isDel = "is_del", sv
    }
    
    // 实现数据库持久化方法
    mutating func didInsert(with rowID: Int, for column: String?) {
        id = rowID
    }
    
    static func createTable(dbQueue: DatabaseQueue) {
        do {
            try dbQueue.write{ db in
                if (try db.tableExists(databaseTableName)) {
                    logger.info("table already exists \(databaseTableName)")
                } else {
                    try db.create(table: databaseTableName) { t in
                        t.autoIncrementedPrimaryKey(Columns.id.rawValue)
                        t.column(Columns.amount.rawValue, .double)
                        t.column(Columns.budgetId.rawValue, .text)
                        t.column(Columns.cid.rawValue, .text)
                        t.column(Columns.bookId.rawValue, .text)
                        t.column(Columns.uid.rawValue, .text)
                        t.column(Columns.createTime.rawValue, .text)
                        t.column(Columns.updateTime.rawValue, .text)
                        t.column(Columns.isTotal.rawValue, .integer)
                        t.column(Columns.isDel.rawValue, .integer)
                        t.column(Columns.sv.rawValue, .integer)
                    }
                    try db.execute(sql: "CREATE UNIQUE INDEX unique_index_budget_id_book_id_uid ON accounting_budget (budget_id, book_id, uid)")
                }
            }
        } catch {
            logger.error("create accounting_book table fail \(error)")
        }
    }
    
    mutating func makeUpdate() {
        self.updateTime = Date().toISODateString()
        // self.sv = Int64(Date().timeIntervalSince1970)
    }
    
    mutating func makeDelete() {
        self.isDel = 1
        self.updateTime = Date().toISODateString()
        // self.sv = Int64(Date().timeIntervalSince1970)
    }
    
    func toJson() -> String {
        do {
            let jsonData = try JSONEncoder().encode(self)
            let jsonStr = String(data: jsonData, encoding: .utf8)
            return jsonStr ?? ""
        } catch {
            logger.error("AccountingBudget toJson fail \(error)")
        }
        return ""
    }
}
